#include "windows.h"
#include "SampleDB.h"
#include <iostream>

CSampleDB::CSampleDB(std::string path, std::string name, int accflag)
	:m_db(NULL, 0), m_dbfile(path + name), accessmethod(accflag)
{
	try
	{
		m_db.set_error_stream(&std::cerr);
		m_db.open(NULL, m_dbfile.c_str(), NULL, (DBTYPE)accessmethod, DB_CREATE, 0);
	}
	catch(DbException &e)
	{
		std::cerr << "Error : Open DB " << m_dbfile << std::endl;
		std::cerr << e.what() << std::endl;
	}
	catch (std::exception &e)
	{
		std::cerr << "Unknown Error " << std::endl;
		std::cerr << e.what() << std::endl;
	}
}

void CSampleDB::CloseDB()
{
	try
	{
		m_db.close(0);
		std::cout << "DB " << m_dbfile << " is closed." << std::endl;
	}
	catch(DbException &e)
	{
		std::cerr << "Error : Close DB " << m_dbfile << std::endl;
		std::cerr << e.what() << std::endl;
	}
	catch(std::exception &e)
	{
		std::cerr << "Unknown Error " << std::endl;
		std::cerr << e.what() << std::endl;
	}
}

void CSampleDB::WriteDB(int num)
{
	try
	{
		int nkey;
		double fdata;
		Dbt	key(&nkey, sizeof(int));
		Dbt data(&fdata, sizeof(double));

		std::cout << "write " << num << " Record, (key length : " << sizeof(int) << ", data length : " << sizeof(double) << std::endl;
		int begintime = GetTickCount();
		for (int i = 0; i < num; ++i)
		{
			nkey = i;
			fdata = i + 0.123456;

			int ret = m_db.put(NULL, &key, &data, DB_NOOVERWRITE);
			if (ret == DB_KEYEXIST)
			{
				m_db.err(ret, "%s put failed because key %d already exists", m_dbfile.c_str(), nkey);
			}
		}
		std::cout << "write " << num << " record take " << GetTickCount() - begintime << " ms." << std::endl;
	}
	catch(DbException &e)
	{
		std::cerr << "Error : Write DB " << m_dbfile << std::endl;
		std::cerr << e.what() << std::endl;
	}
	catch(std::exception &e)
	{
		std::cerr << "Unknown Error " << std::endl;
		std::cerr << e.what() << std::endl;
	}
}

void CSampleDB::ReadDB(int num)
{
	try
	{
		int nkey;
		double fdata;
		Dbt	key(&nkey, sizeof(int));
		Dbt data(&fdata, sizeof(double));
		data.set_ulen(sizeof(double));
		data.set_flags(DB_DBT_USERMEM);

		std::cout << "read " << num << " Record, (key length : " << sizeof(int) << ", data length : " << sizeof(double) << std::endl;

		int begintime = GetTickCount();
		for (int i = 0; i < num; ++i)
		{
			nkey = i;
			m_db.get(NULL, &key, &data, 0);
		}
		std::cout << "read " << num << " record take " << GetTickCount() - begintime << " ms." << std::endl;
	}
	catch(DbException &e)
	{
		std::cerr << "Error : Write DB " << m_dbfile << std::endl;
		std::cerr << e.what() << std::endl;
	}
	catch(std::exception &e)
	{
		std::cerr << "Unknown Error " << std::endl;
		std::cerr << e.what() << std::endl;
	}
}